package main

import (
    "log"
    "path"
    "strconv"
    "strings"
    "sync"
    "time"

    "github.com/360EntSecGroup-Skylar/excelize"
)

// 定义变量只会赋值一次
var onlyOne sync.Once
var myExcel *ExcelInfo

// ExcelInfo Excel信息
type ExcelInfo struct {
    ExcelPath string
    SheetName string
}

// DefaultExcelInfo 定义接口补充默认信息
type DefaultExcelInfo interface {
    getInfo(info *ExcelInfo)
}

// RealizeFunc 定义一个实现接口的函数类型  返回Excel信息
type RealizeFunc func(excelInfo *ExcelInfo)

// getInfo 接口函数方法实现
func (realizeFunc RealizeFunc) getInfo(excelInfo *ExcelInfo) {
    realizeFunc(excelInfo)
}

// excelName 定义函数处理默认excel名称 返回值是实现接口的一个函数
func excelName(excelName string) RealizeFunc {
    if path.Ext(excelName) != ".xlsx" {
        excelName += ".xlsx"
    }
    return func(excelInfo *ExcelInfo) {
        excelInfo.ExcelPath = getCurrentPath() + getPathDelimiter() + excelName
    }
}

// sheetName 定义函数处理默认excel-sheet名称 返回值是实现接口的一个函数
func sheetName(sheetName string) RealizeFunc {
    return func(excelInfo *ExcelInfo) {
        excelInfo.SheetName = sheetName
    }
}

func createExcel(excelInfos ...DefaultExcelInfo) {
    onlyOne.Do(func() {
        myExcel = &ExcelInfo{
            ExcelPath: getCurrentPath() + getPathDelimiter() + time.Now().Format("20060102_150405") + ".xlsx", // 当前时间格式化
            SheetName: "Sheet1"}
    })
    for _, excelInfo := range excelInfos {
        excelInfo.getInfo(myExcel)
    }
    xlsx := excelize.NewFile()
    sheetID := xlsx.NewSheet(myExcel.SheetName)

    if myExcel.SheetName != "Sheet1" {
        xlsx.DeleteSheet("Sheet1")
        log.Printf("删除默认创建Sheet1")
    }

    // 设置活跃的 Sheet
    xlsx.SetActiveSheet(sheetID)
    // 保存Excel文件
    err := xlsx.SaveAs(myExcel.ExcelPath)
    if err != nil {
        log.Printf("保存Excel失败: #%v ", err)
        return
    }
    log.Printf("创建保存Excel成功")
}

func insertExcelRowFromArray(arrayString *[]string, axis string) {
    //log.Printf("insertExcelFromArray: %v ", arrayString)
    xlsx, _ := excelize.OpenFile(myExcel.ExcelPath)
    xlsx.SetSheetRow(myExcel.SheetName, axis, arrayString)
    // 保存Excel文件
    err := xlsx.SaveAs(myExcel.ExcelPath)
    if err != nil {
        log.Printf("按行写入Excel数据后，保存Excel失败: #%v ", err)
        return
    }
    log.Printf("按行写入Excel数据后，创建保存Excel成功")
}

func insertExcelColFromArray(arrayString *[]string, col string, startRowIndex int, colName string, rep repExportInfo) {
    // 打开Excel
    xlsx, _ := excelize.OpenFile(myExcel.ExcelPath)
    // 设置列名称
    xlsx.SetCellValue(myExcel.SheetName, col+"1", colName)
    // 设置单元格样式
    style, err := xlsx.NewStyle(`{
        "font":
        {
            "bold": true,
            "italic": false,
            "family": "仿宋",
            "size": 30,
            "color": "#777777"
        },
        "alignment":
        {
        "horizontal": "center"
        }
    }`)
    if err != nil {
        log.Printf("创建单元格样式失败: #%v ", err)
    }
    xlsx.SetCellStyle(myExcel.SheetName, col+"1", col+"1", style)

    var maxLength int = 0
    // 使用切片值给对应单元格赋值
    for index, value := range *arrayString {
        if rep.RepEnabled {
            value = strings.Replace(value, rep.RepOldWord, rep.RepNewWord, -1)
        }
        xlsx.SetCellValue(myExcel.SheetName, col+strconv.Itoa(index+startRowIndex), value)
        if maxLength < len(value) {
            maxLength = len(value)
        }
    }
    log.Printf("当前单元格最大长度: %d ", maxLength)
    xlsx.SetColWidth(myExcel.SheetName, col, col, float64(maxLength))

    // 保存Excel文件
    err = xlsx.SaveAs(myExcel.ExcelPath)
    if err != nil {
        log.Printf("按列写入Excel数据后，保存Excel失败: #%v ", err)
        return
    }
    log.Printf("按列写入Excel数据后，保存Excel成功")
}
